import PlayerData from "./config/PlayerData";
import MoveSticker from "./joystick/MoveSticker";
import RotateSticker from "./joystick/RotateSticker";
import Hero from "./Hero";
import Utils from "./Utils";
import Global, { Player, PlayerFrame } from "./Global";
import GameState, {Hero as LHero} from "./GameState";

var PlayerType = PlayerData.playerType;

const { ccclass, property } = cc._decorator;

@ccclass
export default class NewClass extends cc.Component {

    @property(cc.Prefab)
    heroPrefab: cc.Prefab = null;
    @property(cc.Label)
    rebornLabel: cc.Label = null;

    localPlayerNode: cc.Node = null;
    loacalPlayerMgr: Hero = null;

    mapRoot: cc.Node = null;
    uiNode: cc.Node = null;
    moveSticker: MoveSticker = null;
    rotateSticker: RotateSticker = null;
    socket: SocketIOClient.Socket = null;
    playerPool: cc.NodePool = null;

    isInit: boolean = false; //游戏是否初始化
    isGaming: boolean = false; //游戏对局是否正在进行
    timestamp: number;
    frameId: number;

    onLoad() {
        if (this.isInit) {
            return;
        }

        this.initViews();   //初始化场景的ui和玩家位置等信息
        this.initListener();

        this.isInit = true;
        this.isGaming = true;

        if (!Global.state) {
            Global.state = new GameState();
            Global.state.initState();
        }

    }

    initViews() {
        this.mapRoot = cc.find("Canvas/mapRoot");
        this.uiNode = cc.find("Canvas/UI");
        this.uiNode.active = false;

        this.initPlayers();
    }

    initPlayers() {
        //初始化全局变量
        Global.playerPos = Object.create(null);
        Global.playerNodes = Object.create(null);
        Global.localPlayer = Object.create(null);
        Global.playerList = new Array();
        //初始化对象池
        this.playerPool = new cc.NodePool();
        let initPlayerCount = 6;
        for (var i = 0; i < initPlayerCount; ++i) {
            var player = cc.instantiate(this.heroPrefab);
            this.playerPool.put(player);
        }

        let playerInfos = Global.room.roomInfo.playerList;
        let players: Player[] = new Array(); //需要处理的玩家信息
        //初始化两队玩家的出生位置
        this.initPlayerPoss(players, playerInfos);

        for (let i = 0; i < players.length; i++) {
            let player = players[i];
            let node = this.addPlayer(player);
            Global.playerNodes[player.playerId] = node;
        }

    }

    //把playerInfos里边的id,teamid拷贝到players数组，并设置pos初始值
    initPlayerPoss(players: Player[], playerInfos: MGOBE.types.PlayerInfo[]) {
        let player: Player = {
            playerId: null,
            angle: 0,
            pos: {},
            teamId: null,
            roomId: Global.room.roomInfo.id,
            isDie: false,
            moveSpeed: 200, //移动速度，单位：像素
            totalBlood: 200,
            blood: 200,
            damage: 20,
            defence: 10,
            lv: 1
        }

        let playerPosis = [
            [
                { x: 200, y: 0 },
                { x: 200, y: 200 },
                { x: 200, y: 400 },
            ],
            [
                { x: 600, y: 0 },
                { x: 600, y: 200 },
                { x: 600, y: 400 },
            ]
        ];

        for (let i = 0; i < playerInfos.length; i++) {
            player.playerId = playerInfos[i].id;
            player.teamId = playerInfos[i].teamId;
            players[i] = Object.create(null);
            (<any>Object).assign(players[i], player);
        }

        let teamId = players[0].teamId;
        let group1 = players.filter(u => u.teamId === teamId);
        let group2 = players.filter(u => u.teamId !== teamId);

        for (let i = 0; i < group1.length; i++) {
            group1[i].pos = playerPosis[0][i];
        }
        for (let i = 0; i < group2.length; i++) {
            group2[i].pos = playerPosis[1][i];
        }
    }

    initListener() {
        this.initSticker();
    }

    sendFrame(){
        let data = {
            playerId: MGOBE.Player.id,
            moveSpeed: this.moveSticker.moveSpeed,
            isMoving: this.moveSticker.isMoving,
            moveRadian: this.moveSticker.lstickRadian,
            rotateRadian: this.rotateSticker.rstickRadian,
            isShooting: this.rotateSticker.isShooting
        }
        Global.room.sendFrame({ data }, (event) => {
            if (event.code === MGOBE.ErrCode.EC_OK) {
                // this.sendList.push(data);
            }
        });
    }

    start() {

        // 检查房间成员与帧广播状态
        Global.room.onUpdate = () => {
            cc.log(`游戏场景帧同步状态：${Global.room.roomInfo.frameSyncState}`)
            if (Global.room.roomInfo.playerList.length !== Global.playerCount || Global.room.roomInfo.frameSyncState === MGOBE.ENUM.FrameSyncState.STOP) {
                Global.room.roomInfo.frameSyncState === MGOBE.ENUM.FrameSyncState.START && Global.room.stopFrameSync({});
                Global.room.onUpdate = null;
                setTimeout(() => cc.director.loadScene("home_scene"), 3000);
            }
        }


        //接收帧同步
        Global.room.onRecvFrame = (event: MGOBE.types.BroadcastEvent<MGOBE.types.RecvFrameBst>) => {
            this.sendFrame();

            let frame: MGOBE.types.Frame = event.data.frame;
            let frameRate = Global.room.roomInfo.frameRate;
            // console.log(`收到帧广播seq:${event.seq}`);
            // console.log(`这帧到达客户端的时间time:${frame.time}`);
            // this.calFrame(frame, frameRate);
            Global.state.calFrame(frame,frameRate);

            //自动补帧不需要拷贝到表现层
            if(event.data.frame.isReplay) return;
            if(!this.isInit || !this.isGaming) return;
           
            Global.state.syncToView();
        }

        cc.game.on("reborn",(playerId)=>{
            let playerNode: cc.Node = Global.playerNodes[playerId];
            let lvTime = 5;     //死亡重生时间
            let ac = cc.fadeOut(0.2);
            playerNode.runAction(ac);
            let hero: LHero = Global.state.heroObjects[playerId];
            //本地玩家倒计时,计时器延时一秒执行以掩盖不能立即执行的bug
            let rebornTime: number = lvTime;
            if (playerId == MGOBE.Player.id) {
                this.rebornLabel.string = rebornTime.toString();
                this.schedule(() => {
                    rebornTime -= 1;
                    if (rebornTime == 0) {
                        this.rebornLabel.string = "";
                    } else {
                        this.rebornLabel.string = rebornTime.toString();
                    }
                }, 1, lvTime - 1, 1);
            }
            //重生
            setTimeout(() => {
                playerNode.opacity = 255;
                playerNode.position = Global.playerPos[playerId];
                hero.isDie = false;
                hero.blood = hero.totalBlood;
                hero.x = playerNode.x;
                hero.y = playerNode.y;
            }, lvTime * 1000);
        });

    }


    /**
     * 掉线
     * @param data 
     */
    offline(data: any) {
        //只删除自己
        if (data.playerId == global.localPlayer.playerId) {
            let node: cc.Node = global.playerNodes[data.playerId];
            node.parent = null;

            for (let i = 0; i < global.playerList.length; i++) {
                if (global.playerList[i] == node) {
                    global.playerList.splice(i, 1);
                }
            }
            this.playerPool.put(node);
        }

    }

    /**
     * 初始化摇杆
     */
    initSticker() {
        //初始化移动摇杆
        this.moveSticker = cc.find("Canvas/UI/lJoystick/lbgstick").getComponent("MoveSticker");
        this.moveSticker.initMove(this.loacalPlayerMgr);

        //初始化右摇杆
        this.rotateSticker = cc.find("Canvas/UI/rJoystick/rbgstick").getComponent("RotateSticker");
        this.rotateSticker.initRotate(this.loacalPlayerMgr);

        this.uiNode.active = true;
    }

    /**
     * 实例化一个玩家
     * @param player 
     */
    addPlayer(player: Player) {
        let playerNode = this.playerPool.get();

        Global.playerPos[player.playerId] = player.pos; //记录下所有人的出生位置坐标

        //获取Hero组件
        let heroMgr: Hero = playerNode.getComponent("Hero");

        if (player.playerId == MGOBE.Player.id) {
            Global.localPlayer = player;
            this.localPlayerNode = playerNode;
            this.loacalPlayerMgr = heroMgr;
        }
        heroMgr.initHero(player);

        //添加到地图节点
        playerNode.parent = this.mapRoot;
        //添加到玩家列表
        Global.playerList.push(playerNode);

        return playerNode;
    }
}
